home *** CD-ROM | disk | FTP | other *** search
- Path: news.th-darmstadt.de!news!enno
- From: enno@inferenzsysteme.informatik.th-darmstadt.de (Enno Sandner)
- Newsgroups: comp.lang.c++
- Subject: Re: Q: Good C++ UNDO Design
- Date: 29 Jan 1996 19:54:15 GMT
- Organization: Fachbereich Informatik, TH Darmstadt
- Distribution: world
- Message-ID: <ENNO.96Jan29205415@kitz.inferenzsysteme.informatik.th-darmstadt.de>
- References: <4eit9g$c6j@news1.halcyon.com>
- NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
- In-reply-to: riston@coho.halcyon.com's message of 29 Jan 1996 16:40:16 GMT
-
- In article <4eit9g$c6j@news1.halcyon.com> riston@coho.halcyon.com (Michael D. Riston) writes:
-
- I have been charged with designing an undo mechanism for a large graphical
- Windows (32bit) application. This application is the classic 'draw a
- shape' program (box, circle, line, OLE object, or whatever). I would like
- to know if anybody has any elegant designs for handling undo operations. I
- am working with Visual C++ 4.0 and MFC for the implementation. I
- am well versed in C++.
-
- A neat solution to this problem is the 'Command' pattern as described in
- the 'Design Patterns' book. The main idea is to encapsulate the necessary
- steps to perform a specific behavior in objects that conform to an unique
- interface. The interface provides the services 'Do' and 'Undo'. It is
- represented by the abstract 'Command' class:
-
- class Command {
- public:
- virtual ~Command() {}
- virtual void Do()=0;
- virtual void Undo()=0;
- };
-
- Every operation that affects the graphical appearence must have its counter-
- part that reverses the operation and both operations should be encapsulated
- in a subclass of 'Command'. For example a circle may look like:
-
- class CircleCommand : public Command {
- public:
- CircleCommand(Painter& p,int x,int y,int r) :
- p_(p), x_(x), y_(y), r_(r) {}
- void Do() { p_.DrawCircle(x_,y_,r_); }
- void Undo() { p_.RemoveCircle(x_,y_,r_); }
- };
-
- Moving a graphical object is another example for an operation that should
- be wrapped.
- Finally you need a manager to register the commands. The manager maintains a
- finite command history and allows you to move backwards and forwards in the
- history. The former results in undoing the latter in executing the command.
-
- Enno
-